﻿using System;
using System.Windows;
using System.Windows.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;

using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV;

namespace WpfFaceDetectionTest
{
    public partial class MainWindow : Window
    {
        DispatcherTimer captureTimer;
        DispatcherTimer recognitionTimer;
        private Capture capture;
        private bool detected;
        private bool isRunning;
        private Image logoImage;
        private List<Image<Bgr, Byte>> videoFrames;
        private int videoIndex = 0;
        private const int fps = 60;

        public MainWindow()
        {
            InitializeComponent();
            Recognition.Initialize();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            capture = new Capture(CaptureType.DSHOW);

            logoImage = Image.FromFile("Test2.png");

            captureTimer = new DispatcherTimer();
            captureTimer.Tick += Capture_Tick;
            captureTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000 / fps);
            captureTimer.Start();

            recognitionTimer = new DispatcherTimer();
            recognitionTimer.Tick += Recognition_Tick;
            recognitionTimer.Interval = new TimeSpan(0, 0, 0, 2, 0);
            recognitionTimer.Start();
        }

        private void Capture_Tick(object sender, EventArgs e)
        {
            try
            {
                using (var capturedFrame = capture.QueryFrame())
                {
                    var currentFrame = capturedFrame;
                    if (capturedFrame != null)
                    {
                        if (detected && !isRunning)
                            ChooseVideo();

                        if (isRunning)
                        {
                            currentFrame = videoFrames[videoIndex];
                            currentFrame = ImageUtils.MergeWithFrame(currentFrame, logoImage);
                            CheckVideoEnding();
                        }

                        image1.Source = ImageUtils.ToBitmapSource(currentFrame);
                    }

                    currentFrame.Dispose();
                }
            }
            catch (Exception Ex)
            {
                Reset();
            }
        }

        private void Recognition_Tick(object sender, EventArgs e)
        {
            try
            {
                using (var currentFrame = capture.QueryGrayFrame())
                {
                    if (currentFrame != null)
                        detected = Recognition.HasDetected(currentFrame, RecognitionType.Face);
                }
            }
            catch (Exception Ex)
            {
                Reset();
            }
        }

        private void Reset()
        {
            detected = false;
            isRunning = false;
            recognitionTimer.Start();
        }

        private void ChooseVideo()
        {
            Reset();

            //create random selection
            videoFrames = VideoUtils.GetVideoFrames("V57-6.mov").ToList();
            videoIndex = 0;
            isRunning = true;
            recognitionTimer.Stop();
        }

        private void CheckVideoEnding()
        {
            videoIndex++;

            if (videoIndex - 1 == videoFrames.Count - 1)
                Reset();
        }
    }
}
